package com.example.personalizededucationsystem.service.recommendation;

import com.example.personalizededucationsystem.model.KnowledgePoint;
import com.example.personalizededucationsystem.model.Question;
import com.example.personalizededucationsystem.model.User;
import com.example.personalizededucationsystem.repository.KnowledgePointRepository;
import com.example.personalizededucationsystem.repository.QuestionRepository;
import com.example.personalizededucationsystem.service.AnalysisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service("weakestPointStrategy")
public class WeakestPointStrategy implements RecommendationStrategy {

    private static final Set<Question.QuestionType> allowedTypes = Set.of(
            Question.QuestionType.SINGLE_CHOICE,
            Question.QuestionType.MULTIPLE_CHOICE
    );
    private final AnalysisService analysisService;
    private final KnowledgePointRepository knowledgePointRepository;
    private final QuestionRepository questionRepository;

    @Autowired
    public WeakestPointStrategy(AnalysisService analysisService, KnowledgePointRepository knowledgePointRepository, QuestionRepository questionRepository) {
        this.analysisService = analysisService;
        this.knowledgePointRepository = knowledgePointRepository;
        this.questionRepository = questionRepository;
    }

    @Override
    public List<Question> recommend(User student, String subject, int count) {
        Map<String, Double> masteryMap = analysisService.calculateStudentMastery(student, subject);
        if (masteryMap.isEmpty()) {
            return Collections.emptyList();
        }

        List<KnowledgePoint> allKps = knowledgePointRepository.findAll();
        Map<String, Long> kpNameToIdMap = allKps.stream()
                .filter(kp -> subject.equals(kp.getSubject()))
                .collect(Collectors.toMap(KnowledgePoint::getName, KnowledgePoint::getKpId));

        if (kpNameToIdMap.isEmpty()) {
            return Collections.emptyList();
        }

        List<Long> weightedKpPool = new ArrayList<>();
        for (Map.Entry<String, Double> entry : masteryMap.entrySet()) {
            Long kpId = kpNameToIdMap.get(entry.getKey());
            if (kpId != null) {
                int weight = (int) Math.ceil((1.0 - entry.getValue()) * 10);
                for (int i = 0; i < weight; i++) {
                    weightedKpPool.add(kpId);
                }
            }
        }

        if (weightedKpPool.isEmpty()) {
            return Collections.emptyList();
        }
        Collections.shuffle(weightedKpPool);

        Set<Long> recommendedQuestionIds = new HashSet<>();
        List<Question> recommendedQuestions = new ArrayList<>();

        for (Long kpId : weightedKpPool) {
            if (recommendedQuestions.size() >= count) break;

            List<Question> foundQuestions = questionRepository.findApprovedQuestionsByKnowledgePointIds(
                    Collections.singletonList(kpId), PageRequest.of(0, count)
            );
            Collections.shuffle(foundQuestions);

            for (Question q : foundQuestions) {
                if (allowedTypes.contains(q.getType()) &&
                        recommendedQuestionIds.add(q.getQuestionId())) {
                    recommendedQuestions.add(q);
                }
                if (recommendedQuestions.size() >= count) break;
            }
        }

        return recommendedQuestions;
    }


    @Override
    public String getStrategyName() {
        return "WEAKEST_POINT";
    }
}